<template>
    <div v-if="checkAllKey !== '99'">
        <el-checkbox
            v-model="checkAll"
            class="d-inline mr-28"
            :indeterminate="indeterminate"
            @change="checkAllChange"
        >
            {{ checkAllName }}
        </el-checkbox>
        <el-checkbox-group
            v-if="fullNewOptions"
            v-model="curVal"
            class="ml-28"
            @change="checkedChange"
        >
            <el-checkbox
                v-for="item in newOptions"
                :key="item.value"
                :label="item.value"
                :value="item.value"
                :disabled="item.disabled"
            >
                <div class="flex-ju-al-center">
                    <div>{{ item.label }}</div>
                    <template v-if="item.value === '99'">
                        <slot name="other"></slot>
                    </template>
                </div>
            </el-checkbox>
        </el-checkbox-group>
        <div v-else>
            <slot name="other"></slot>
        </div>
    </div>
</template>
<script>
export default {
    name: 'com-allCheckbox',
    props:{
        checkAllKey:{
            type: String,
        },
        checkAllName:{
            type:String,
            default:'全选'
        },
        options:{
            type: [Array,Function],
            default: ()=>[]
        },
        value:{
            type: Array,
            default:()=>[]
        },
    },
    data(){
        return {
            curVal:this.value,
            newOptions:[],
            indeterminate:true,
            checkAll:false
        };
    },
    computed:{
        curOptions(){
            let curOptions = [];
            if(Array.isArray(this.newOptions) && this.newOptions.length){
                if(typeof this.newOptions[0] === 'string'){
                    curOptions = [...this.newOptions];
                }else{
                    curOptions = this.newOptions.map(item=>item.value);
                }
            }
            return curOptions;
        },
        fullNewOptions(){
            return Boolean(Array.isArray(this.newOptions) && this.newOptions.length);
        }
    },
    watch:{
        /**
         * @method v-model逻辑，数据发生变化时，则input给父组件
         */
        'value'(val){
            this.curVal = val;
            this.getInitVal();
        },
    },
    async created(){
        // 初始化
        if(typeof this.options === 'function'){
            this.newOptions = await this.options();
        }else{
            this.newOptions = [...this.options];
        }
    },
    methods: {
        /**
         * @method 点击全选按钮的逻辑操作
         */
        checkAllChange(val){
            this.curVal = val ? this.curOptions : [];
            this.indeterminate = false;
            this.$emit('input',this.curVal);
        },
        /**
         * @method 点击单个checkbox的逻辑操作
         */
        checkedChange(val){
            let checkedCount = val.length;
            this.checkAll = checkedCount === this.curOptions.length;
            this.indeterminate = checkedCount > 0 && checkedCount < this.curOptions.length;
            this.$emit('input',this.curVal);
        },
        /**
         * @method 初始化
         * @desc 根据value和optopns（均为label组成的数组），初始化全选状态和indeterminate属性
         */
        getInitVal(){
            let val = this.dataEqualArray(this.curOptions,this.value);
            console.log(this.curOptions,this.value,val);
            this.indeterminate = !val;
            this.checkAll = val;
        },
        /**
         * @method 处理所有checkbox选项，比较两个数组的值是否一致
         * @param arr1 所有-allOptions
         * @param arr2 选项-value
         */
        // 判断两个数组的值是否一致
        dataEqualArray(arr1, arr2) {
            if(!Array.isArray(arr1) || !Array.isArray(arr2)){
                return false;
            }
            if(arr1.length !== arr2.length){
                return false;
            }
            for(let i = 0, len = arr2.length; i < len; i++){
                if(arr1.indexOf(arr2[i]) !== -1 && arr2.indexOf(arr1[i]) !== -1){
                    return true;
                }
            }
            return false;
        },
    }
};
</script>